<template>
  <div id="bottom">
    <canvas
      id="canvas"
      @mousedown="down($event)"
      @mousemove="move($event)"
      @mouseup="up"
      @mouseenter="enter"
      @touchstart="start($event)"
      @touchmove="move2($event)"
      @touchend="up"
    ></canvas>
  </div>
</template>

<script>
import bus from "../utils/eventBus";
import { saveAs } from "file-saver";

export default {
  name: "bottom",
  data() {
    return {
      canvas: {},
      cxt: {},
      width: 0,
      height: 0,
      startPoint: {
        x: 0,
        y: 0,
      },
      endPoint: {
        x: 0,
        y: 0,
      },
      paint: false, // 是否开启画笔
      eraser: false, // 是否开启橡皮擦
      history: [], // 操作历史记录
      color: "#000000",
      value: 1,
    };
  },

  created() {
    this.width = document.documentElement.clientWidth;
    this.height = document.documentElement.clientHeight * 0.9;

    bus.$on("pencilColor", (value) => {
      this.color = value;
    });

    bus.$on("pencilWidth", (value) => {
      this.value = value;
    });

    bus.$on("pencil", (_message) => {
      this.paint = true;
      this.eraser = false;
    });

    bus.$on("back", (_message) => {
      this.$nextTick(() => {
        this.cancel();
      });
    });

    bus.$on("delete", (_message) => {
      this.$nextTick(() => {
        this.remove();
      });
    });

    bus.$on("eraser", (_message) => {
      this.eraser = true;
      this.paint = false;
    });

    bus.$on("download", (_message) => {
      this.$nextTick(() => {
        this.download();
      });
    });

    bus.$on("upload", (_value) => {
      this.$nextTick(() => {
        this.upload();
      });
    });
  },

  mounted() {
    this.init();
  },

  methods: {
    init() {
      let that = this;
      that.canvas = document.getElementById("canvas");
      that.cxt = that.canvas.getContext("2d");

      // 不这样设置canvas内容不显示！！！！！！！！
      canvas.width = that.width;
      canvas.height = that.height;

      let image = this.cxt.getImageData(0, 0, this.width, this.height);
      this.history.push(image);
    },

    enter() {
      // 修复pc端使用橡皮擦之后进入canvas立即开始画线
      this.paint = false;
    },

    cancel() {
      // 撤回上一步
      this.history.pop();

      if (this.history.length == 1) {
        this.cxt.putImageData(this.history[this.history.length - 1], 0, 0);
        bus.$emit("disabled", "禁用撤回");
      } else {
        this.cxt.putImageData(this.history[this.history.length - 1], 0, 0);
      }
    },

    down(e) {
      // 鼠标按下事件
      const x = e.offsetX;
      const y = e.offsetY;

      this.startPoint = {
        x: x,
        y: y,
      };

      if (this.eraser) {
        this.cxt.clearRect(x, y, 10, 10);
      }

      this.paint = true;
    },

    move(e) {
      // 鼠标移动事件
      e.preventDefault();
      const x = e.offsetX;
      const y = e.offsetY;

      this.endPoint = {
        x: x,
        y: y,
      };

      if (this.paint) {
        if (this.eraser) {
          this.cxt.clearRect(x, y, 10, 10);
        } else {
          this.draw();
        }
      }

      this.startPoint.x = this.endPoint.x;
      this.startPoint.y = this.endPoint.y;
    },

    up() {
      // 鼠标松开事件
      let image = this.cxt.getImageData(0, 0, this.width, this.height);
      this.history.push(image);
      bus.$emit("abled", "启用撤回");
      this.paint = false;
    },

    remove() {
      // 清空画布
      this.cxt.fillStyle = "#ffebce";
      this.cxt.clearRect(0, 0, this.width, this.height);
    },

    draw() {
      // 开始绘制
      this.cxt.beginPath();
      // 设置线条样式
      this.cxt.lineWidth = this.value;
      this.cxt.lineCap = "round";
      this.cxt.lineJoin = "round";
      this.cxt.strokeStyle = this.color;
      //起始位置
      this.cxt.moveTo(this.startPoint.x, this.startPoint.y);
      //停止位置
      this.cxt.lineTo(this.endPoint.x, this.endPoint.y);
      //描绘线路
      this.cxt.stroke();
      //结束绘制
      this.cxt.closePath();
    },

    start(e) {
      //[0]表示touch第一个触碰点
      let x = e.touches[0].clientX;
      let y = e.touches[0].clientY;

      this.startPoint = {
        x: x,
        y: y,
      };

      if (this.eraser) {
        this.cxt.clearRect(x, y, 10, 10);
      }

      this.paint = true;
    },

    move2(e) {
      e.preventDefault();
      let x = e.touches[0].clientX;
      let y = e.touches[0].clientY;
      this.endPoint = {
        x: x,
        y: y,
      };

      if (this.paint) {
        if (this.eraser) {
          this.cxt.clearRect(x, y, 10, 10);
        } else {
          this.draw();
        }
      }

      this.startPoint.x = this.endPoint.x;
      this.startPoint.y = this.endPoint.y;
    },

    download() {
      this.canvas.toBlob(function (blob) {
        const time = new Date().getTime();
        saveAs(blob, `${time}.png`);
      });
    },

    upload() {
      this.$prompt("请输入答案", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        center: true,
      })
        .then(({ value }) => {
          this.$message({
            type: "success",
            message: "内容: " + value,
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "取消输入",
          });
        });
    },
  },
};
</script>

<style scoped>
#bottom {
  width: 100vw;
  background-color: #ffebce;
}
</style>
